<template>
  <div class="dynamic-form">
    <el-form
      :disabled="readonly"
      ref="formRef"
      :model="formData"
      :rules="formRules"
      :label-width="formConfig.form.labelWidth || '120px'"
      :label-position="formConfig.form.labelPosition || 'right'"
      @submit.prevent="handleSubmit"
    >
      <el-row :gutter="20">
        <template v-for="field in formConfig.form.fields" :key="field.id">
          <el-col
            v-if="shouldShowField(field)"
            :span="colSet(field)"
          >
            <el-form-item
              :label="field.label"
              :prop="field.id"
              :required="field.required"
            >
              <!-- 文本输入框 -->
              <el-input
                v-if="field.type === 'text'"
                v-model="formData[field.id]"
                :placeholder="field.placeholder"
                :clearable="field.clearable !== false"
                :disabled="field.disabled"
              />

              <!-- 密码输入框 -->
              <el-input
                v-else-if="field.type === 'password'"
                v-model="formData[field.id]"
                type="password"
                :placeholder="field.placeholder"
                :show-password="true"
                :disabled="field.disabled"
              />

              <!-- 邮箱输入框 -->
              <el-input
                v-else-if="field.type === 'email'"
                v-model="formData[field.id]"
                type="email"
                :placeholder="field.placeholder"
                :disabled="field.disabled"
              />

              <!-- 数字输入框 -->
              <el-input-number
                v-else-if="field.type === 'number'"
                v-model="formData[field.id]"
                :min="field.validation?.min"
                :max="field.validation?.max"
                :step="field.step || 1"
                :disabled="field.disabled"
                controls-position="right"
              />

              <!-- 文本域 -->
              <el-input
                v-else-if="field.type === 'textarea'"
                v-model="formData[field.id]"
                type="textarea"
                :placeholder="field.placeholder"
                :rows="field.rows || 3"
                :maxlength="field.validation?.maxLength"
                :show-word-limit="!!field.validation?.maxLength"
                :disabled="field.disabled"
              />

              <!-- 下拉选择 -->
              <el-select
                v-else-if="field.type === 'select'"
                v-model="formData[field.id]"
                :placeholder="field.placeholder || '请选择'"
                :clearable="field.clearable !== false"
                :multiple="field.multiple"
                :disabled="field.disabled"
                style="width: 100%"
              >
                <el-option
                  v-for="option in field.options"
                  :key="option.value"
                  :label="option.label"
                  :value="option.value"
                />
              </el-select>

              <!-- 单选按钮组 -->
              <el-radio-group
                v-else-if="field.type === 'radio'"
                v-model="formData[field.id]"
                :disabled="field.disabled"
              >
                <el-radio
                  v-for="option in field.options"
                  :key="option.value"
                  :label="option.value"
                >
                  {{ option.label }}
                </el-radio>
              </el-radio-group>

              <!-- 复选框 -->
              <el-checkbox
                v-else-if="field.type === 'checkbox'"
                v-model="formData[field.id]"
                :disabled="field.disabled"
              >
                {{ field.label }}
              </el-checkbox>

              <!-- 复选框组 -->
              <el-checkbox-group
                v-else-if="field.type === 'checkbox-group'"
                v-model="formData[field.id]"
                :disabled="field.disabled"
              >
                <el-checkbox
                  v-for="option in field.options"
                  :key="option.value"
                  :label="option.value"
                >
                  {{ option.label }}
                </el-checkbox>
              </el-checkbox-group>

              <!-- 日期选择器 -->
              <el-date-picker
                v-else-if="field.type === 'date'"
                v-model="formData[field.id]"
                type="date"
                :placeholder="field.placeholder || '请选择日期'"
                :disabled="field.disabled"
                style="width: 100%"
              />

              <!-- 日期时间选择器 -->
              <el-date-picker
                v-else-if="field.type === 'datetime'"
                v-model="formData[field.id]"
                type="datetime"
                :placeholder="field.placeholder || '请选择日期时间'"
                :disabled="field.disabled"
                style="width: 100%"
              />

              <!-- 滑块 -->
              <el-slider
                v-else-if="field.type === 'slider'"
                v-model="formData[field.id]"
                :min="field.validation?.min || 0"
                :max="field.validation?.max || 100"
                :step="field.step || 1"
                :show-input="field.showInput"
                :disabled="field.disabled"
              />

              <!-- 评分 -->
              <el-rate
                v-else-if="field.type === 'rate'"
                v-model="formData[field.id]"
                :max="field.max || 5"
                :allow-half="field.allowHalf"
                :disabled="field.disabled"
              />

              <!-- 开关 -->
              <el-switch
                v-else-if="field.type === 'switch'"
                v-model="formData[field.id]"
                :active-text="field.activeText"
                :inactive-text="field.inactiveText"
                :disabled="field.disabled"
              />

              <!-- 文件上传 -->
              <el-upload
                v-else-if="field.type === 'file'"
                v-model:file-list="fileLists[field.id]"
                :action="field.uploadAction || ''"
                :multiple="field.multiple"
                :limit="field.limit"
                :accept="field.accept"
                :disabled="field.disabled"
                :auto-upload="false"
              >
                <el-button type="primary">点击上传</el-button>
              </el-upload>
              <!-- 帮助文本 -->
              <div v-if="field.helpText" class="help-text">
                {{ field.helpText }}
              </div>
            </el-form-item>
          </el-col>
        </template>
      </el-row>

      <!-- 表单操作按钮 -->
      <el-form-item v-if="!readonly">
        <el-button
          type="primary"
          native-type="submit"
          :loading="submitLoading"
        >
          {{ formConfig.form.actions?.submit?.label || '提交' }}
        </el-button>
        <el-button @click="resetForm">
          {{ formConfig.form.actions?.reset?.label || '重置' }}
        </el-button>
        <slot name="actions"></slot>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts">
import {ref, reactive, onMounted, watch, computed, nextTick} from 'vue'
import type {FormInstance, FormRules, UploadUserFile} from 'element-plus'
import type {
  DynamicFormConfig,
  FormField,
  FormData,
} from '@/types'

// 定义 props
interface Props {
  formConfig: DynamicFormConfig
  modelValue?: FormData
  //只读
  readonly?: boolean
  id?: string
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: () => ({}),
  readonly: false
})

// 定义 emits
const emit = defineEmits<{
  (e: 'update:modelValue', value: FormData): void
  (e: 'submit', data: FormData): void
  (e: 'reset'): void
}>()

// 表单引用
const formRef = ref<FormInstance>()

// 表单数据
const formData = reactive<FormData>({})
const fileLists = reactive<Record<string, UploadUserFile[]>>({})
const submitLoading = ref(false)

// 生成表单验证规则
const generateRules = (field: FormField): FormRules => {
  const rules: FormRules = {}

  if (field.required) {
    rules[field.id] = [
      {
        required: true,
        message: `${field.label} 是必填项`,
        trigger: ['blur', 'change']
      }
    ]
  }

  if (field.validation) {
    const fieldRules = rules[field.id] as any[] || [] as any[]

    // 长度验证
    if (field.validation.minLength !== undefined) {
      fieldRules.push({
        min: field.validation.minLength,
        message: `最少输入 ${field.validation.minLength} 个字符`,
        trigger: 'blur'
      })
    }

    if (field.validation.maxLength !== undefined) {
      fieldRules.push({
        max: field.validation.maxLength,
        message: `最多输入 ${field.validation.maxLength} 个字符`,
        trigger: 'blur'
      })
    }

    // 正则表达式验证
    if (field.validation.pattern) {
      fieldRules.push({
        pattern: new RegExp(field.validation.pattern),
        message: field.validation.message || '输入格式不正确',
        trigger: 'blur'
      })
    }

    // 自定义验证器
    if (field.validation.validator) {
      fieldRules.push({
        validator: field.validation.validator,
        trigger: 'blur'
      })
    }

    rules[field.id] = fieldRules
  }

  return rules
}

// 表单验证规则
const formRules = computed<FormRules>(() => {
  const rules: FormRules = {}
  props.formConfig.form.fields.forEach(field => {
    Object.assign(rules, generateRules(field))
  })
  return rules
})

// 条件字段显示判断
const shouldShowField = (field: FormField): boolean => {
  if (!props.formConfig.form.conditions) return true

  // 简单的条件判断实现
  // 可以根据实际需求扩展更复杂的条件逻辑
  return true
}

const colSet = (field: FormField): number => {
  if(props.formConfig.form.column){
    return 24/props.formConfig.form.column
  }
  return field.span || 24
}


// 初始化表单数据
// 替换整个 onMounted 函数
onMounted(() => {
  initializeFormData()
})



// 移除之前的所有初始化相关代码，使用这个简化版本
const initializeFormData = () => {
  // 清空当前表单数据
  Object.keys(formData).forEach(key => {
    delete formData[key]
  })

  // 重新根据配置设置所有字段
  props.formConfig.form.fields.forEach(field => {
    // 设置默认值
    if (field.defaultValue !== undefined) {
      formData[field.id] = field.defaultValue
    } else if (field.type === 'checkbox-group') {
      formData[field.id] = []
    } else if (field.type === 'checkbox' || field.type === 'switch') {
      formData[field.id] = false
    } else {
      formData[field.id] = ''
    }

    // 初始化文件列表
    if (field.type === 'file') {
      fileLists[field.id] = []
    }
  })

  // 同步外部传入的值
  if (props.modelValue && Object.keys(props.modelValue).length > 0) {
    Object.assign(formData, props.modelValue)
  }
}
// 监听表单数据变化
watch(formData, (newVal) => {
  emit('update:modelValue', newVal)
}, { deep: true, immediate: true })
// 监听字段变化，重新初始化数据
watch(
  () => props.formConfig,
  (newConfig) => {
    if (newConfig && newConfig.form && newConfig.form.fields) {
      nextTick(() => {
        initializeFormData()
      })
    }
  },
  { deep: true, immediate: true }
)
// 提交表单
const handleSubmit = async () => {
  if (!formRef.value) return

  try {
    await formRef.value.validate()
    submitLoading.value = true

    // 合并文件数据
    const submitData = {...formData}
    Object.keys(fileLists).forEach(key => {
      submitData[key] = fileLists[key]
    })

    emit('submit', submitData)
  } catch (error) {
    console.error('表单验证失败:', error)
  } finally {
    submitLoading.value = false
  }
}

// 重置表单
const resetForm = () => {
  if (formRef.value) {
    formRef.value.resetFields()
  }

  // 重置文件列表
  Object.keys(fileLists).forEach(key => {
    fileLists[key] = []
  })

  emit('reset')
}

// 暴露方法给父组件
defineExpose({
  validate: () => formRef.value?.validate(),
  resetFields: resetForm,
  clearValidate: () => formRef.value?.clearValidate()
})
</script>

<style scoped>
.dynamic-form {
  padding: 20px;
}

:deep(.el-form-item) {
  margin-bottom: 22px;
}

:deep(.help-text) {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
  line-height: 1.5;
}

/* 可选：为帮助文本添加图标 */
:deep(.help-text.with-icon) {
  position: relative;
  padding-left: 20px;
}

:deep(.help-text.with-icon::before) {
  content: "ℹ️";
  position: absolute;
  left: 0;
  top: 1px;
}
</style>
